﻿using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using AmuTools.SFExpress.dto;

namespace AmuTools.SFExpress
{
    public class SFService
    {
        #region 属性
        public string ClientCode { get; private set; }
        public string CheckWord { get; private set; }
        public string ReqUrl
        {
            get
            {
                return "https://bsp-oisp.sf-express.com/bsp-oisp/sfexpressService";
            }
        }
        #endregion

        #region 构造函数
        public SFService(string clientCode, string checkWord)
        {
            ClientCode = clientCode;
            CheckWord = checkWord;
        }
        #endregion

        #region 下订单
        public Response<OrderResponseDto> Order(OrderRequestDto orderRequest)
        {
            return GetResponse<OrderRequestDto, OrderResponseDto>("OrderService", orderRequest);
        }
        #endregion

        #region 订单结果查询
        public Response<OrderSearchResponseDto> OrderSearch(OrderSearchRequestDto orderRequest)
        {
            return GetResponse<OrderSearchRequestDto, OrderSearchResponseDto>("OrderSearchService", orderRequest);
        }
        #endregion

        #region 加密与请求
        public Response<TResponse> GetResponse<TRequest, TResponse>(string serviceName, TRequest tRequest)
        {
            SFXMLHelper sxh = new SFXMLHelper();
            string xml = sxh.CreateRequestToXml<TRequest>(serviceName, tRequest);
            string responseXml = Query(xml);
            Response<TResponse> response = sxh.CreateResponseFromXml<TResponse>(serviceName, responseXml);
            return response;
        }

        public string Query(string xml)
        {
            string verifyCode = MD5ToBase64String(xml + CheckWord);
            return querySFAPIservice(ReqUrl, xml, verifyCode);
        }

        public string MD5ToBase64String(string str)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] MD5 = md5.ComputeHash(Encoding.UTF8.GetBytes(str));//MD5(注意UTF8编码) 
            string result = Convert.ToBase64String(MD5);//Base64 
            return result;
        }

        public bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            // 总是接受 
            return true;
        }

        public string querySFAPIservice(string reqUrl, string xml, string verifyCode)
        {
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult); string postData = string.Format("xml={0}&verifyCode={1}", xml, verifyCode); //请求 
            WebRequest request = (HttpWebRequest)WebRequest.Create(reqUrl);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
            request.ContentLength = Encoding.UTF8.GetByteCount(postData);
            byte[] postByte = Encoding.UTF8.GetBytes(postData);
            Stream reqStream = request.GetRequestStream();
            reqStream.Write(postByte, 0, postByte.Length);
            reqStream.Close(); //读取 
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();
            return retString;
        }
        #endregion
    }
}
